<template>
<div class="bh-slider"
	:class="{'is-vertical': vertical}"
	@mousedown="onButtonDown"
	@touchstart="onButtonDown">
	<div class="bh-slider__runway" :class="[disabled ? 'disabled':'']" :style="runwayStyle">
		<div class="bh-slider__bar" :style="barStyle"></div>
		<div class="bh-slider__button-wrapper" :style="wrapperStyle">
			<div class="bh-tooltip bh-slider__button" :title='formatValue'></div>
		</div>
	</div>
</div>
</template>

<script>
export default {
	name: 'bh-slider',
	props: {
		value: {
			type: Number,
			default: 0
		},
		step: {
			type: Number,
			default: 1
		},
		disabled: {
			type: Boolean,
			default: false
		},
		vertical: {
			type: Boolean,
			default: false
		},
		height: String,
	},
	data() {
		return {
			dragging: false,
			startPosition: 0,
			newPosition: 0,
			startX: 0,
			startY: 0,
			currentX: 0,
			sliderSize: 1,
		}
	},
	computed: {
		currentPosition() {
			return `${ (this.value - this.min) / (this.max - this.min) * 100 }%`;
		},
		formatValue() {
			return this.value
		},
		runwayStyle() {
			return this.vertical ? { height: this.height } : {};
		},
		barStyle() {
			return this.vertical ? {
				'height': this.formatValue + '%',
				'bottom': '0px',
			} : {'width': this.formatValue + '%'};
		},
		wrapperStyle() {
			return this.vertical ? {'bottom': this.formatValue + '%'} : {'left': this.formatValue + '%'};
		},
		max() {
			return 100;
		},
		min() {
			return 0;
		},
    },
	methods: {
		onButtonDown(event) {
			if (this.disabled) return;
			event.preventDefault();
			this.onDragStart(event);
			window.addEventListener('mousemove', this.onDragging);
			window.addEventListener('touchmove', this.onDragging);
			window.addEventListener('mouseup', this.onDragEnd);
			window.addEventListener('touchend', this.onDragEnd);
			window.addEventListener('contextmenu', this.onDragEnd);
		},
		onDragStart(event) {
			this.dragging = true;
			console.log('onDragStart', event.type);
			if (event.type === 'touchstart') {
				event.clientY = event.touches[0].clientY;
				event.clientX = event.touches[0].clientX;
			}
			if (this.vertical) {
				this.startY = event.clientY;
			} else {
				this.startX = event.clientX;
			}
			this.startPosition = parseFloat(this.currentPosition);
			this.newPosition = this.startPosition;
		},
		onDragging(event) {
			if (this.dragging) {
				let diff = 0;
				if (this.vertical) {
					this.currentY = event.clientY;
					diff = (this.startY - this.currentY) / this.sliderSize * 100;
				} else {
					this.currentX = event.clientX;
					diff = (this.currentX - this.startX) / this.sliderSize * 100;
				}
				this.newPosition = this.startPosition + diff;
				this.setPosition(this.newPosition);
			}
		},
		onDragEnd() {
			if(this.dragging) {
				window.removeEventListener('mousemove', this.onDragging);
				window.removeEventListener('touchmove', this.onDragging);
				window.removeEventListener('mouseup', this.onDragEnd);
				window.removeEventListener('touchend', this.onDragEnd);
				window.removeEventListener('contextmenu', this.onDragEnd);
				setTimeout(() => {
					this.dragging = false;
				}, 0)
			}
		},
		setPosition(newPosition) {
			if (newPosition < 0) {
				newPosition = 0;
			} else if (newPosition > 100) {
				newPosition = 100;
			}

			const lengthPerStep = 100 / ((this.max - this.min) / this.step);
			const steps = Math.round(newPosition / lengthPerStep);
			let value = steps * lengthPerStep * (this.max - this.min) * 0.01 + this.min;
			value = parseFloat(value.toFixed(this.precision));
			this.$emit('input', value);
		},
	},
	mounted() {
		//获取元素的宽或高
		this.sliderSize = this.$el[`client${ this.vertical ? 'Height' : 'Width' }`];
	},
}
</script>
